package user

import (
	"container/list"
	"sync"
)

type Linklist struct {
	*list.List
	lock *sync.RWMutex
	m    *list.List
}

func (l *Linklist)GetLock() (*sync.RWMutex) {
	return l.lock
}

func (l *Linklist) AddM(value interface{}) {
	if l.m == nil {
		l.m = list.New()
	}
	l.m.PushBack(value)
}

func (l *Linklist) GetDelMS() []interface{} {
	l.lock.RLock()
	if l.m != nil {
		data := make([]interface{},l.m.Len())
		for {
			if l.m.Len() == 0 {
				break
			}
			el := l.m.Back()
			data[l.m.Len()-1] = el.Value
			l.m.Remove(el)
		}
		l.lock.RUnlock()
		return data
	}
	l.lock.RUnlock()
	return nil
}

func (l *Linklist) Add(value UserConn) {
	l.lock.Lock()
	contain, _ := l.Contains(value)
	if !contain {
		l.PushFront(value)
	}
	l.lock.Unlock()
}
func (l *Linklist) HasLocal() bool {
	l.lock.RLock()
	for e := l.Front(); e != nil; e = e.Next() {
		cn, ok := e.Value.(UserConn)
		if ok {
			if cn.IsLocal() {
				l.lock.RUnlock()
				return true
			}
		}
	}
	l.lock.RUnlock()
	return false
}

func (l *Linklist) Delete(value UserConn) {
	l.lock.Lock()



	contain, e := l.Contains(value)
	if contain {
		l.Remove(e)
	}
	l.lock.Unlock()
}
func (l *Linklist) DeleteAll() {
	l.lock.Lock()
	for {
		if l.Len() == 0 {
			break
		}
		l.Remove(l.Front())
	}
	l.lock.Unlock()

}

func (l *Linklist) GetArray(start int, num int) []UserConn {
	l.lock.RLock()
	data := make([]UserConn, 0)
	var index = 0
	for e := l.Front(); e != nil; e = e.Next() {
		if index >= start && index < (start+num) {
			vv, ok := e.Value.(UserConn)
			if ok {
				data = append(data, vv)
			}
		}
		if index >= (start + num) {
			break
		}
		index++
	}
	l.lock.RUnlock()
	return data
}
func (l *Linklist) GetAllArray() []UserConn {
	l.lock.RLock()
	data := make([]UserConn, 0)
	for e := l.Front(); e != nil; e = e.Next() {
		vv, ok := e.Value.(UserConn)
		if ok {
			data = append(data, vv)
		}
	}
	l.lock.RUnlock()
	return data
}

func (l *Linklist) Contains(value UserConn) (bool, *list.Element) {
	for e := l.Front(); e != nil; e = e.Next() {
		if e.Value == value {
			return true, e
		}
	}
	return false, nil
}
